/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.diagram.component.helper;
import java.util.ArrayList;

import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.uml2.uml.Component;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.PackageableElement;
import org.eclipse.uml2.uml.PrimitiveType;
import org.eclipse.uml2.uml.UMLFactory;

import com.cea.papyrus.core.helper.NodeHelper;
import com.cea.papyrus.core.utils.Debug;
import com.cea.papyrus.diagram.component.Activator;
import com.cea.papyrus.diagram.component.preference.ComponentDiagramPreferenceConstants;
import com.cea.papyrus.diagraminterchange2.di2.Diagram;
import com.cea.papyrus.diagraminterchange2.di2.GraphElement;
import com.cea.papyrus.diagraminterchange2.di2.GraphNode;
import com.cea.papyrus.diagraminterchange2.di2.Uml1SemanticModelBridge;


/**
 * Factory that can create and delete a {@link PrimitiveType}}.
 * 
 * @author A. Lanusse
 */
public class NodeInterfaceHelper extends NodeHelper{
	
	///////////////////////////////////////////////////////////////////////////
    // UML Management
    ///////////////////////////////////////////////////////////////////////////
	
	
	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.factories.NodeFactory#canExecuteCreateElement(org.eclipse.uml2.uml.Element)
	 */
	@Override
	public boolean canCreateUMLElement(Element umlParent) {
		if (umlParent instanceof Component ||umlParent instanceof Package) {
			return true;
		}
		return false;
	}
	
	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.factories.NodeFactory#createElement(java.lang.String, org.eclipse.uml2.uml.Element)
	 */

	@Override
	public org.eclipse.uml2.uml.Element createUMLElement(String name, org.eclipse.uml2.uml.Element umlParent) {
		Debug.debug(this,"Call NodePrimitiveTypeFactory.createPrimitiveType()", channel); //$NON-NLS-1$

		// create PrimitiveType
		org.eclipse.uml2.uml.Interface anInterface=UMLFactory.eINSTANCE.createInterface();
		anInterface.setName(name);
		
//		((Package)umlParent).getPackagedElements().add(anInterface);
		if (umlParent instanceof Component) {
			((Component)umlParent).getPackagedElements().add(anInterface);
			} 
		else if (umlParent instanceof Package) {
			((Package)umlParent).getPackagedElements().add(anInterface);
		}
		return anInterface;
	}
	
	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.factories.NodeFactory#addElement(org.eclipse.uml2.uml.Element, org.eclipse.uml2.uml.Element)
	 */
	@Override
	public boolean addUMLElement(Element element, Element umlParent) {
		if (umlParent instanceof Component || umlParent instanceof Package) {
			return ((Package)umlParent).getPackagedElements().add((PackageableElement)element);
		}
		return false;
	}
	
	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.factories.NodeFactory#removeElement(org.eclipse.uml2.uml.Element, org.eclipse.uml2.uml.Element)
	 */
	@Override
	public boolean removeUMLElement(Element element, Element umlParent) {
		if (umlParent instanceof Component ||umlParent instanceof Package){
			return ((Package)umlParent).getPackagedElements().remove(element);
		}
		return false;
	}
	
	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.factories.NodeFactory#getBaseString()
	 */
	@Override
	public String getBaseString() {
		return "Interface_"; //$NON-NLS-1$
	}
	
	///////////////////////////////////////////////////////////////////////////
    // GraphNode Management
    ///////////////////////////////////////////////////////////////////////////

	/*
	 * (non-Javadoc)
	 * @see com.cea.papyrus.common.factories.NodeFactory#canExecuteCreateCommand(com.cea.papyrus.diagraminterchange2.di2.GraphNode)
	 */

	@Override
	public boolean canCreateGraphElement(GraphElement parent){
		if(parent instanceof Diagram) {
			return true;
		} else if (parent.getSemanticModel()!=null){
			Element parentElt= ((Uml1SemanticModelBridge)parent.getSemanticModel()).getElement();
			if(parentElt!=null){
				if (parentElt instanceof Component || parentElt instanceof Package) {
					return true;
				}
			}
		}
		return false;
	}
	
	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.factories.NodeFactory#createGraphNode(org.eclipse.uml2.uml.NamedElement, com.cea.papyrus.diagraminterchange2.di2.Diagram)
	 */

	@Override
	public ArrayList createGraphNode(Element umlElement, Diagram diagram) {
		Debug.debug(this,"Call NodePrimitiveTypeFactory.createGraphNode()", channel); //$NON-NLS-1$
		return new ArrayList();
	}
	
	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.factories.NodeFactory#createGraphElement(org.eclipse.uml2.uml.Element, com.cea.papyrus.diagraminterchange2.di2.GraphElement, org.eclipse.draw2d.geometry.Point, org.eclipse.draw2d.geometry.Dimension)
	 */
	/**
	 * 
	 * 
	 * @param umlChild 
	 * @param size 
	 * @param location 
	 * @param pordNode this is the GraphNode that is associated to the portNode
	 * 
	 * @return the graphNode of the interface
	 */
	@Override
	public GraphNode createGraphElement(Element umlChild, GraphElement nodeElement, Point location, Dimension size) {
		Debug.debug(this,"Call NodeInterfaceFactory.createGraphElement()", channel); //$NON-NLS-1$
		
		// Creates the graph element corresponding to the Primitive Type
		GraphNode graphNode=null;
		GraphElement parent= null;
		// The nodeElement can be a port or a component (it is the semantic parent)
		// We have to determine the right parent (container) of the graphNode
		// In both cases parent is nodeElement.getContainer();
		parent =nodeElement.getContainer();

		// IMPORTANT -- on graphNode creation, the parent argument must be null
		// This is to avoid the early creation of the corresponding EditPart by GEF
		// i.e. before the SemanticParent is set
		// The graphNode is added to the parent contained elements afterwards
		graphNode = super.createGraphElement(umlChild, null, location, size);
		graphNode.setSemanticParent(nodeElement);
		graphNode.setSize(new Dimension(20, 20));
		
		// Now we can add it to the container
//		parent.getContained().add(graphNode);
		nodeElement.getContainer().getContained().add(graphNode);
		
		// We do the same for graphNodeName
		GraphNode graphNodeName = super.createGraphElement(null, null, new Point(location.x+40, location.y+20), size);
		graphNodeName.setSemanticParent(graphNode);
		// finally, adds the PrimitiveType graph element to its parent graph element
//		parent.getContained().add(graphNodeName);
		nodeElement.getContainer().getContained().add(graphNodeName);
		return graphNode;
	}
	
	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.helper.NodeHelper#setGraphElementPreferences(com.cea.papyrus.diagraminterchange2.di2.GraphElement)
	 */

	@Override
	public void setGraphElementPreferences(GraphElement graphElement) {
		// Get the preference store
		IPreferenceStore store = Activator.getDefault().getPreferenceStore();

		// Set colors and font
		graphElement.setBackgroundColor(ComponentDiagramPreferenceConstants.getPreferenceInterfaceBackgroundColor(store));
		graphElement.setBorderColor(ComponentDiagramPreferenceConstants.getPreferenceInterfaceBorderColor(store));
		graphElement.setFontColor(ComponentDiagramPreferenceConstants.getPreferenceInterfaceFontColor(store));
		FontData[] fontdata = ComponentDiagramPreferenceConstants.getPreferenceInterfaceFont(store);
		if (fontdata.length>0){
			graphElement.setFontFamily(fontdata[0].getName());
			graphElement.setFontSize(fontdata[0].getHeight());
		}
	}
}


